package com.sky.templateMethod;

/**
 * <p>
 * date : 2020-08-20
 * 模板方法模式架构
 * <p>
 * 模板方法模式包含以下主要角色。
 * <p>
 * (1) 抽象类（Abstract Class）：负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。这些方法的定义如下。
 * <p>
 * ① 模板方法：定义了算法的骨架，按某种顺序调用其包含的基本方法。
 * <p>
 * ② 基本方法：是整个算法中的一个步骤，包含以下几种类型。
 * 抽象方法：在抽象类中申明，由具体子类实现。
 * 具体方法：在抽象类中已经实现，在具体子类中可以继承或重写它。
 * 钩子方法：在抽象类中已经实现，包括用于判断的逻辑方法和需要子类重写的空方法两种。
 * <p>
 * (2) 具体子类（Concrete Class）：实现抽象类中所定义的抽象方法和钩子方法，它们是一个顶级逻辑的一个组成步骤。
 *
 * @author : wushikai
 */
public class TemplateMethod {

    public static void main(String[] args) {
        AbstractClass abstractClass = new ConcreteClass();
        abstractClass.templateMethod();
    }


}


/**
 * 抽象类
 */
abstract class AbstractClass {

    public void templateMethod( ) {
        hookMethod1();
        if(hookMethod2()) {

            specificMethod();
        }
        abstractMethod1();
        abstractMethod2();
    }

    //这个方法对于同类型来说都是一样的; 是共性;
    public void specificMethod( ) {

        System.out.println("抽象类中的具体方法被调用");
    }

    //这些方法就是每个对象的特性;
    public abstract void abstractMethod1( );

    public abstract void abstractMethod2( );

    public void hookMethod1( ) {}

    public boolean hookMethod2( ) {

        return true;
    }


}


/**
 * 具体子类
 */
class ConcreteClass extends AbstractClass {


    @Override
    public void hookMethod1( ) {
        System.out.println("钩子方法1被重写...");
    }

    @Override
    public void abstractMethod1( ) {
        System.out.println("抽象方法1的实现被调用...");
    }

    @Override
    public void abstractMethod2( ) {
        System.out.println("抽象方法2的实现被调用...");
    }

    public boolean hookMethod2( ) {

        return false; //把钩子设置为false , 则父类中的具体方法将不会被调用, 在子类控制了父类方法的流程;
    }
}


